package cn.mumzone.pos.presenter;

import android.text.TextUtils;
import android.view.View;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sunmi.payment.PaymentService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import cn.mumzone.basic.mvp.AbsPresenter;
import cn.mumzone.basic.net.http.callback.ApiCallBack;
import cn.mumzone.basic.net.response.BaseResponse;
import cn.mumzone.basic.net.response.PageListResponse;
import cn.mumzone.basic.util.BigDecimalUtil;
import cn.mumzone.basic.util.DeviceIdUtils;
import cn.mumzone.basic.util.ListUtil;
import cn.mumzone.basic.util.MoneyFormatUtil;
import cn.mumzone.basic.util.PatternUtils;
import cn.mumzone.basic.util.RxBus;
import cn.mumzone.basic.util.StringUtils;
import cn.mumzone.basic.util.log.Elog;
import cn.mumzone.pos.AppConstants;
import cn.mumzone.pos.BuildConfig;
import cn.mumzone.pos.event.MemberBindEvent;
import cn.mumzone.pos.event.NetConnectedEvent;
import cn.mumzone.pos.event.SettleDiscountEvent;
import cn.mumzone.pos.model.BillDetailEntity;
import cn.mumzone.pos.model.GoodsEntity;
import cn.mumzone.pos.model.LoginEntity;
import cn.mumzone.pos.model.MemberAccountEntity;
import cn.mumzone.pos.model.MemberEntity;
import cn.mumzone.pos.model.OrderVoEntity;
import cn.mumzone.pos.model.ServerEntity;
import cn.mumzone.pos.model.ServiceEntity;
import cn.mumzone.pos.model.SettleCalculatePriceEntity;
import cn.mumzone.pos.model.SettleDiscountAreaEntity;
import cn.mumzone.pos.model.SettleResultEntity;
import cn.mumzone.pos.model.ShopUserEntity;
import cn.mumzone.pos.model.SunMiPayRequestEntity;
import cn.mumzone.pos.model.TicketEntity;
import cn.mumzone.pos.model.TimeCardEntity;
import cn.mumzone.pos.model.source.AppRepository;
import cn.mumzone.pos.model.source.BillsRepository;
import cn.mumzone.pos.model.source.GoodsRepository;
import cn.mumzone.pos.model.source.MemberRepository;
import cn.mumzone.pos.model.source.ReserveRepository;
import cn.mumzone.pos.model.source.SettleRepository;
import cn.mumzone.pos.model.source.UserRepository;
import cn.mumzone.pos.presenter.contract.SettleAccountContract;
import cn.mumzone.pos.ui.activity.ACT_SettleAccounts;
import cn.mumzone.pos.util.AppUtil;
import cn.mumzone.pos.util.BillUtil;
import cn.mumzone.pos.util.PayCountDownTimer;
import rx.Subscription;
import rx.functions.Action1;

import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_ACTIVITY;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_ACTIVITY_BALANCE;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_ACTIVITY_DISCOUNT;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_BALANCE;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_CASH;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_COUPON;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_DISCOUNT_COUPON;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_ERASE_ZERO;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_EXP_COUPON;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_INTEGRAL_DEDUCTION;
import static cn.mumzone.pos.model.SettleCalculatePriceEntity.DiscountItemBean.TYPE_TIMES_CARD;


/**
 * Created by lijiateng on 2018/12/12.
 */

public class SettleAccountPresenter extends AbsPresenter<SettleAccountContract.View, SettleRepository>
        implements SettleAccountContract.Presenter {

    public static final int CODE_BANK_TIME_OUT = 504;
    public static final int CODE_SUN_MI_TIME_OUT = 505;
    public static final int CODE_SUN_MI_NET_ERROR = 506;
    public static final int CODE_INVENTORY_ERROR = 507;
    public static final int CODE_SUN_MI_QUERY_TIME_OUT = 508;
    public static final int CODE_BUSINESS_ERROR = 401;

    private static final int STORE_TYPE_COMPANY = 1;//会员余额-公司账户
    private static final int STORE_TYPE_SHOP = 2;//会员余额-门店账户

    private BillsRepository mBillRepo;
    private MemberRepository memberRepository;
    private UserRepository userRepository;
    private ReserveRepository reserveRepository;
    private GoodsRepository goodsRepository;

    private boolean isExecutedScan;

    // 商品、服务结账信息
    private String phone;
    private String goodsJson;
    private String memberId;
    private String memberIntegral;
    private String howMoneyOne;
    private String levelId;
    private MemberEntity memberEntity;
    private MemberAccountEntity memberAccount;
    private String orderType;
    private String settleType;
    private boolean isGoodSaved;
    private String appointmentId;

    // 优惠活动信息，操作后实时由 View 层传入 P 层
    private List<TicketEntity> activityList = new ArrayList<>();
    private List<TicketEntity> tickets = new ArrayList<>();
    private List<TicketEntity> preTickets = new ArrayList<>();
    private List<TimeCardEntity> timesCards = new ArrayList<>();
    private int selectedIndex = 0;
    private int preIndex = 0;
    private String mlAmount;
    private String integral;
    private OrderVoEntity orderVo;

    // 结账金额信息
    private String salesmanId;
    private String totalAmount;
    private String toPayAmount;
    private double eraseAmount;

    // 结账订单信息
    private String saleId;

    // 记录支付方式
    private HashMap<String, String> payTypeMap = new HashMap<>();
    //记录次卡已选次数
    private HashMap<String, String> timeCardNumMap = new HashMap<>();

    private List<GoodsEntity> integralList = new ArrayList<>();

    private int storeType;

    //补偿相关
    private PayCountDownTimer payCountDownTimer;
    private static final int COUNT_DOWN_TIME = 125;
    private boolean isFacePay = false;

    private HashMap<String, TicketEntity> addedPayMap = new HashMap<>();

    private String orderId = "";
    private boolean isFirstSunMiTimeOut = true;
    private boolean isSunMiPay = false;

    private boolean isDiscountReturn = false;
    private boolean isCalculateReturn = false;

    private boolean isSunMiNetError = false;


    /**
     * 构造器方法
     * <p>
     * 在其中对优惠活动的删除进行监听并且重置
     */
    public SettleAccountPresenter() {
        Subscription subscribe = RxBus.getDefault().toObservable(SettleDiscountEvent.class)
                .subscribe(new Action1<SettleDiscountEvent>() {
                    @Override
                    public void call(SettleDiscountEvent settleDiscountEvent) {
                        SettleCalculatePriceEntity.DiscountItemBean itemBean = settleDiscountEvent.getItem();
                        switch (itemBean.getDiscountType()) {
                            case TYPE_ACTIVITY_BALANCE:
                            case TYPE_ACTIVITY_DISCOUNT:
                                for (TicketEntity ticket : activityList) {
                                    if (ticket.getTicketId().equals(itemBean.getId())) {
                                        activityList.remove(ticket);
                                        break;
                                    }
                                }
                                setActivity(activityList);
                                mView.showCouponSelectedChange(TYPE_ACTIVITY, ListUtil.deepCopy(activityList));
                                break;
                            case TYPE_COUPON:
                            case TYPE_EXP_COUPON:
                            case TYPE_DISCOUNT_COUPON:
                                for (TicketEntity ticket : tickets) {
                                    if (ticket.getId().equals(itemBean.getId())) {
                                        tickets.remove(ticket);
                                        break;
                                    }
                                }
                                setTicket(tickets);
                                mView.showCouponSelectedChange(TYPE_COUPON, ListUtil.deepCopy(tickets));
                                break;
                            case TYPE_ERASE_ZERO:
                                SettleAccountPresenter.this.mlAmount = "";
                                eraseAmount = 0;
                                calculateGoodsAmount();
                                break;
                            case TYPE_TIMES_CARD:
                                for (TimeCardEntity timeCard : timesCards) {
                                    if (timeCard.getId().equals(itemBean.getId())) {
                                        timesCards.remove(timeCard);
                                        break;
                                    }
                                }
                                setMemberTimesCardId(timesCards);
                                mView.showTimeCardSelectedChange(ListUtil.deepCopy(timesCards));
                                break;
                            case TYPE_CASH:
                                addedPayMap.remove(BillUtil.PAY_TYPE_CASH);
                                calculateGoodsAmount();
                                break;
                            case TYPE_BALANCE:
                                addedPayMap.remove(BillUtil.PAY_TYPE_BALANCE);
                                calculateGoodsAmount();
                                break;
                            case TYPE_INTEGRAL_DEDUCTION:
                                addedPayMap.remove(BillUtil.PAY_TYPE_INTEGRAL);
                                calculateGoodsAmount();
                                break;
                        }
                    }
                });
        addSubscrebe(subscribe);

        payCountDownTimer = new PayCountDownTimer(COUNT_DOWN_TIME * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                super.onTick(millisUntilFinished);
                Elog.e("TAG----", millisUntilFinished);
                long time = millisUntilFinished / 1000;
                mView.showTimeChanged(time);
                if (time <= COUNT_DOWN_TIME - 120) {
                    if (isFirstSunMiTimeOut) {
                        querySmPayOrderInfo(false);
                        isFirstSunMiTimeOut = false;
                    }
                }
            }

            @Override
            public void onFinish() {
                super.onFinish();
                mView.showSunMiPayNetError();
                mView.showTimeChanged(COUNT_DOWN_TIME);

            }
        };

        Subscription netConnectListener = RxBus.getDefault()
                .toObservable(NetConnectedEvent.class)
                .subscribe(new Action1<NetConnectedEvent>() {
                    @Override
                    public void call(NetConnectedEvent netConnectedEvent) {
                        if (isSunMiNetError) {
                            isSunMiNetError = false;
                            querySmPayOrderInfo(true);
                        }
                    }
                });
        addSubscrebe(netConnectListener);

        if (LoginEntity.STORE_TYPE_COMPANY == AppConstants.TEMP_SHOP_STORE_TYPE) {
            storeType = STORE_TYPE_COMPANY;
        } else {
            storeType = STORE_TYPE_SHOP;
        }
    }

    @Override
    protected void initOtherRepository() {
        mBillRepo = new BillsRepository();
        memberRepository = new MemberRepository();
        userRepository = new UserRepository();
        reserveRepository = new ReserveRepository();
        goodsRepository = new GoodsRepository();
    }


    /**
     * 找零弹窗确认支付
     *
     * @param cashChange
     * @param cashInput
     */
    @Override
    public void settleOrderWithCashChange(String cashChange, String cashInput) {
        requestSaveOrder("", cashChange, cashInput, "", JSON.toJSONString(payTypeMap), false);
    }


    /**
     * 设置会员手机号，如果手机号为空，同时将 memberId 置空
     *
     * @param phone
     */
    public void setPhone(String phone) {
        this.phone = phone;
        if (TextUtils.isEmpty(phone)) {
            memberId = "";
            levelId = "";
            memberEntity = null;
        }
    }

    /**
     * 设置抹零金额
     * 设置完成后重新计算待收金额，以下几个方法作用以及原理均相同
     *
     * @param mlAmount 抹零金额
     * @return
     */
    public boolean setMlAmount(String mlAmount) {
        String formattedMoney = MoneyFormatUtil.getFormattedMoney(mlAmount, false);
        if (TextUtils.isEmpty(formattedMoney)) {
            mView.showError("输入金额有误");
            return false;
        }
        this.mlAmount = mlAmount;
        mView.showLoadingDialog();
        calculateGoodsAmount();
        return true;
    }

    public boolean setMemberTimesCardId(List<TimeCardEntity> timesCards) {

        for (TimeCardEntity timesCard : timesCards) {
            TimeCardEntity bean = checkTimeCardInList(timesCard, this.timesCards);
            if (null == bean) {
                selectedIndex = selectedIndex + 1;
                timesCard.setIndex(selectedIndex);
            } else {
                timesCard.setIndex(bean.getIndex());
            }
        }
        this.timesCards = timesCards;
        calculateGoodsAmount();
        return true;
    }

    private TimeCardEntity checkTimeCardInList(TimeCardEntity timesCard, List<TimeCardEntity> timesCards) {
        for (TimeCardEntity bean : timesCards) {
            if (bean.getId().equals(timesCard.getId())) {
                return bean;
            }
        }
        return null;
    }

    private TicketEntity checkTicketInList(TicketEntity ticket, List<TicketEntity> tickets) {
        for (TicketEntity bean : tickets) {
            if (bean.getId().equals(ticket.getId())) {
                return bean;
            }
        }
        return null;
    }


    public boolean setTicket(List<TicketEntity> tickets) {
//        preTickets = this.tickets;
        for (TicketEntity ticket : tickets) {
            TicketEntity bean = checkTicketInList(ticket, this.tickets);
            if (null == bean) {
                selectedIndex = selectedIndex + 1;
                ticket.setIndex(selectedIndex);
            } else {
                ticket.setIndex(bean.getIndex());
            }
        }
        this.tickets = tickets;
        calculateGoodsAmount();
        return true;
    }

    private TicketEntity checkActivityInList(TicketEntity ticket, List<TicketEntity> tickets) {
        for (TicketEntity bean : tickets) {
            if (bean.getTicketId().equals(ticket.getTicketId())) {
                return bean;
            }
        }
        return null;
    }

    public boolean setActivity(List<TicketEntity> activityList) {

        for (TicketEntity ticket : activityList) {
            TicketEntity bean = checkActivityInList(ticket, this.activityList);
            if (null == bean) {
                selectedIndex = selectedIndex + 1;
                ticket.setIndex(selectedIndex);
            } else {
                ticket.setIndex(bean.getIndex());
            }
        }
        this.activityList = activityList;
        calculateGoodsAmount();
        return true;
    }

    public boolean isMlSelected() {
        if (!StringUtils.isEmpty(mlAmount)) {
            mView.showError("抹零后不能使用其他优惠");
            return true;
        }
        return false;
    }

    public void setSalesmanId(String salesmanId) {
        this.salesmanId = salesmanId;
    }

    public void setIntegral(String integral) {
        this.integral = integral;
        calculateGoodsAmount();
    }

    public String getSalesmanId() {
        return salesmanId;
    }


    /**
     * 重置所有和会员相关的信息
     */
    public void resetMemberStatusAndRefresh() {
        this.phone = "";
        this.memberId = "";
        this.levelId = "";
        memberEntity = null;
        this.memberIntegral = "";
        this.howMoneyOne = "";
        this.addedPayMap.clear();
        this.mlAmount = "";
        memberAccount = null;
        this.tickets = new ArrayList<>();
        this.activityList = new ArrayList<>();
        this.timesCards = new ArrayList<>();
        this.integralList = new ArrayList<>();
        this.integral = "";
        mView.showCouponSelectedChange(TYPE_COUPON, ListUtil.deepCopy(tickets));
        mView.showCouponSelectedChange(TYPE_ACTIVITY, ListUtil.deepCopy(activityList));
        mView.showTimeCardSelectedChange(timesCards);
        mView.showRedeemGoodsChange(integralList);

        getMemberOrBillInfo();
        if (!StringUtils.isEmpty(appointmentId)) {
            doUpdateReserveMember(appointmentId, null);
        } else {
            RxBus.getDefault().post(new MemberBindEvent(null));
        }
    }

    /**
     * 将一些需要用到的值传递到 P 层使用
     *
     * @param phone       手机号
     * @param goodsJson   商品 json
     * @param orderType   订单类型，0：商品；1：服务  2:次卡
     * @param isGoodSaved 当前是否寄存
     */
    public void initVariable(String phone, String goodsJson, String orderType, String settleType, boolean isGoodSaved) {
        this.phone = phone;
        this.goodsJson = goodsJson;
        this.orderType = orderType;
        this.settleType = settleType;
        this.isGoodSaved = isGoodSaved;
        if (orderType.equals(ACT_SettleAccounts.SETTLE_ORDER_TYPE_SERVICE) ||
                orderType.equals(ACT_SettleAccounts.SETTLE_ORDER_TYPE_BABY_SWIM)) {
            List<ServiceEntity> entities = JSON.parseArray(goodsJson, ServiceEntity.class);
            appointmentId = entities.get(0).getAppointmentId();
        }
    }

    @Override
    public void executeScanCode(String scanCode) {
        if (!isExecutedScan) {
            boolean isAliPay = payTypeMap.containsKey(BillUtil.PAY_TYPE_ALI);

//            if(isAliPay){
//                if(!PatternUtils.isAliPayCode(scanCode)){
//                    mView.showError("请扫描支付宝付款码");
//                    isExecutedScan = false;
//                    mView.resetScanCodeStatus();
//                    return;
//                }
//            }else {
//                if(!PatternUtils.isWxPayCode(scanCode)){
//                    mView.showError("请扫描微信付款码");
//                    isExecutedScan = false;
//                    mView.resetScanCodeStatus();
//                    return;
//                }
//            }
            requestSaveOrder(scanCode, "", "", "", JSON.toJSONString(payTypeMap), false);
            mView.showWaitingDialog(isAliPay);
            payCountDownTimer.reset();
            payCountDownTimer.start();
        }
        isExecutedScan = true;
        mView.resetScanCodeStatus();
    }

    /**
     * 调用现金完成支付
     *
     * @param cashInput
     */
    public void settleOrderWithCash(String cashInput) {


        if (isGoodSaved && TextUtils.isEmpty(memberId)) {
            mView.showError("当前有寄存商品，请绑定会员后重试");
            return;
        }

        // 屏蔽错误格式
        String formattedMoney = MoneyFormatUtil.getFormattedMoney(cashInput, true);
        if (TextUtils.isEmpty(formattedMoney)) {
            mView.showError("输入金额有误");
            return;
        }

        // 输入金额小于待收金额时，截断
        if (Double.parseDouble(cashInput) < Double.parseDouble(this.toPayAmount)) {
            TicketEntity cashPay = new TicketEntity();
            cashPay.setTicketName("现金");
            cashPay.setTicketType(TYPE_CASH);
            cashPay.setTicketAmount(cashInput);
            cashPay.setIndex(selectedIndex);
            TicketEntity oldCashPay = addedPayMap.get(BillUtil.PAY_TYPE_CASH);
            if (oldCashPay != null) {
                cashPay.setIndex(oldCashPay.getIndex());
                cashPay.setTicketAmount(String.valueOf(BigDecimalUtil.add(cashPay.getTicketAmount(), oldCashPay.getTicketAmount())));
            }
            addedPayMap.put(BillUtil.PAY_TYPE_CASH, cashPay);
            mView.showAddedPay();
            mView.showLoadingDialog();
            calculateGoodsAmount();
            return;
        }

        // 更新支付方式，计算找零金额，发起支付
        updatePayTypeMap(true, BillUtil.PAY_TYPE_CASH, toPayAmount);
        double cashChange = Double.parseDouble(cashInput) - Double.parseDouble(this.toPayAmount);
        if (cashChange <= 0) {
            if (cashChange < 0)
                cashChange = 0;
            mView.showLoadingDialog();
            requestSaveOrder("", StringUtils.get(cashChange), cashInput, "", JSON.toJSONString(payTypeMap), false);
        } else {
            mView.showCashChangeDialog(String.valueOf(cashChange), cashInput);
        }

    }

    /**
     * 调使用会员余额完成支付
     *
     * @param memberBalance 会员余额
     */
    public void settleOrderWithMemberBalance(String memberBalance, boolean isSelectShopPrice) {


        String memberAccountBalance = isSelectShopPrice ? memberAccount.getShopPrice() : memberAccount.getCompanyPrice();

        TicketEntity oldBalancePay = addedPayMap.get(BillUtil.PAY_TYPE_BALANCE);
        String selectBalance = "";
        if (oldBalancePay != null) {
            selectBalance = String.valueOf(BigDecimalUtil.add(memberBalance, oldBalancePay.getTicketAmount()));
        } else {
            selectBalance = memberBalance;
        }
        if (Double.parseDouble(selectBalance) > Double.parseDouble(memberAccountBalance)) {
            mView.showError("会员余额不足");
            return;
        }
        storeType = isSelectShopPrice ? STORE_TYPE_SHOP : STORE_TYPE_COMPANY;
        if (Double.parseDouble(memberBalance) < Double.parseDouble(this.toPayAmount)) {
            TicketEntity balancePay = new TicketEntity();
            balancePay.setTicketName("会员余额");
            balancePay.setTicketType(TYPE_BALANCE);
            balancePay.setTicketAmount(memberBalance);
            balancePay.setIndex(selectedIndex);
            if (oldBalancePay != null) {
                balancePay.setIndex(oldBalancePay.getIndex());
                balancePay.setTicketAmount(String.valueOf(BigDecimalUtil.add(balancePay.getTicketAmount(), oldBalancePay.getTicketAmount())));
            }
            addedPayMap.put(BillUtil.PAY_TYPE_BALANCE, balancePay);
            mView.showAddedPay();
            mView.showLoadingDialog();
            calculateGoodsAmount();
            return;
        }

        if (Double.parseDouble(memberBalance) > Double.parseDouble(this.toPayAmount)) {
            mView.showError("支付金额不能大于待收金额~");
            return;
        }

        // 更新支付方式，发起支付
        updatePayTypeMap(true, BillUtil.PAY_TYPE_BALANCE, toPayAmount);
        mView.showLoadingDialog();
        requestSaveOrder("", "", "", "", JSON.toJSONString(payTypeMap), false);

    }


    public void settleOrderWithIntegral(String integralMoney) {

        String integralNum = String.valueOf(BigDecimalUtil.mul(integralMoney, howMoneyOne));

        if (Double.parseDouble(BigDecimalUtil.getNumber(howMoneyOne)) == 0) {
            mView.showError("抵扣规则有误");
            return;
        }

        if (!PatternUtils.isWholeNumbers(integralNum)) {
            mView.showError("不能使用小数个积分~");
            return;
        }

        integralNum = StringUtils.getWholeNumber(integralNum);


        TicketEntity oldIntegralPay = addedPayMap.get(BillUtil.PAY_TYPE_INTEGRAL);

        int selectIntegral = Integer.parseInt(integralNum);
        String selectIntegralMoney = integralMoney;
        if (oldIntegralPay != null) {
            selectIntegral = Integer.parseInt(integralNum) + Integer.parseInt(oldIntegralPay.getIntegral());
            selectIntegralMoney = String.valueOf(BigDecimalUtil.add(integralMoney, oldIntegralPay.getTicketAmount()));
        }

        if (selectIntegral > Double.parseDouble(memberIntegral)) {
            mView.showError("会员积分不足");
            return;
        }
        if (Double.parseDouble(integralMoney) < Double.parseDouble(this.toPayAmount)) {
            TicketEntity integralPay = new TicketEntity();
            integralPay.setTicketType(TYPE_INTEGRAL_DEDUCTION);
            integralPay.setTicketAmount(selectIntegralMoney);
            integralPay.setIntegral(String.valueOf(selectIntegral));
            integralPay.setIndex(selectedIndex);
            if (oldIntegralPay != null) {
                integralPay.setIndex(oldIntegralPay.getIndex());
            }
            integralPay.setTicketName("积分抵现");

            addedPayMap.put(BillUtil.PAY_TYPE_INTEGRAL, integralPay);
            mView.showAddedPay();
            mView.showLoadingDialog();
            calculateGoodsAmount();
            return;
        }

        if (Double.parseDouble(integralMoney) > Double.parseDouble(this.toPayAmount)) {
            mView.showError("抵扣金额不能大于待收金额~");
            return;
        }

        // 更新支付方式，发起支付
        updatePayTypeMap(true, BillUtil.PAY_TYPE_INTEGRAL, toPayAmount);

        requestSaveOrder("", "", "", integralNum, JSON.toJSONString(payTypeMap), false);

    }

    public void settleOrderWithMemberBalance() {

        // 对会员登录做校验
        if (TextUtils.isEmpty(memberId)) {
            mView.showError("请登录会员后重试");
            return;
        }

        // 如果待收金额为 0 ，不允许使用此支付方式
        if (Double.parseDouble(toPayAmount) <= 0) {
            mView.showError("当前支付方式不可用，请使用现金完成支付");
            return;
        }

        if (memberAccount == null || (StringUtils.isEmpty(memberAccount.getCompanyPrice())
                && StringUtils.isEmpty(memberAccount.getShopPrice()))) {
            mView.showError("会员账户数据为空");
            return;
        }

        if (memberAccount != null && BigDecimalUtil.add(BigDecimalUtil.getNumber(memberAccount.getCompanyPrice()),
                BigDecimalUtil.getNumber(memberAccount.getShopPrice())) == 0) {
            mView.showError("会员余额不足");
            return;
        }
        // 弹窗等待用户输入，之后调起支付
        mView.showPayDialog(BillUtil.PAY_TYPE_BALANCE);

    }


    public void settleOrderWithMemberIntegral() {

        // 对会员登录做校验
        if (TextUtils.isEmpty(memberId)) {
            mView.showError("请登录会员后重试");
            return;
        }

        // 如果待收金额为 0 ，不允许使用此支付方式
        if (Double.parseDouble(toPayAmount) <= 0) {
            mView.showError("当前支付方式不可用，请使用现金完成支付");
            return;
        }


        if (TextUtils.isEmpty(memberIntegral) || Double.parseDouble(BigDecimalUtil.getNumber(memberIntegral)) == 0) {
            mView.showError("会员积分不足");
            return;
        }

        if (TextUtils.isEmpty(howMoneyOne) || Double.parseDouble(BigDecimalUtil.getNumber(howMoneyOne)) == 0) {
            mView.showError("未开启积分抵现~");
            return;
        }
        // 弹窗等待用户输入，之后调起支付
        mView.showPayDialog(BillUtil.PAY_TYPE_INTEGRAL);

    }

    /**
     * 使用微信或者支付宝完成支付
     *
     * @param payType 支付方式
     */
    public void settleOrderOnline(String payType) {

        // 有寄存的情况下，需要绑定会员
        if (isGoodSaved && TextUtils.isEmpty(memberId)) {
            mView.showError("当前有寄存商品，请绑定会员后重试");
            return;
        }

        // 如果待收金额为 0 ，不允许使用此支付方式
        if (Double.parseDouble(toPayAmount) <= 0) {
            mView.showError("当前支付方式不可用，请使用现金完成支付");
            return;
        }

        // 设置支付方式，弹窗等待扫码结果后调起支付
        updatePayTypeMap(true, payType, toPayAmount);

        //银行卡区别展示 拉卡拉和记账弹窗
        if (BillUtil.PAY_TYPE_BANK.equals(payType)) {
            if (orderVo != null && "1".equals(orderVo.getPayCnl())) { // 0 原生 1 中金 2 商米
                mView.showPayDialog(BillUtil.PAY_TYPE_BANK_POS);
            } else {
                mView.showPayDialog(payType);
            }
        } else {
            mView.showPayDialog(payType);
        }

    }

    /**
     * 使用银行卡完成支付
     */
    public void settleOrderWithBank() {
        if (orderVo != null && "1".equals(orderVo.getPayCnl())) { // 0 原生 1 中金 2 商米
            mView.showBankWaitingDialog();
        }

        // 更新支付方式，发起支付
        updatePayTypeMap(true, BillUtil.PAY_TYPE_BANK, toPayAmount);
        requestSaveOrder("", "", "", "", JSON.toJSONString(payTypeMap), false);

    }

    /**
     * 更新 payType 值
     *
     * @param payType        支付方式
     * @param currTypeAmount 当前支付方式的待支付金额
     */
    public void updatePayTypeMap(boolean isAdd, String payType, String currTypeAmount) {
        if (isAdd) {
            payTypeMap.clear();
            payTypeMap.put(payType, currTypeAmount);
        } else {
            payTypeMap.remove(payType);
        }
    }

    @Override
    public void getMemberOrBillInfo() {
        this.addedPayMap.clear();
        this.mlAmount = "";
        // 如果是从上个页面带入了会员信息，则直接请求会员详情接口
        if (requestMemberInfo()) return;


        // 查询商品价格以及优惠券信息
//        if (orderType.equals(ACT_SettleAccounts.SETTLE_ORDER_TYPE_GOODS)) {
//            syncRemoteGoodsPrice();
//        } else {
        calculateGoodsAmount();
        requestDiscountAreaInfo();
//        }

    }

    /**
     * 请求结账界面左下角优惠信息
     */
    private void requestDiscountAreaInfo() {

        ApiCallBack<SettleDiscountAreaEntity> callback = new ApiCallBack<SettleDiscountAreaEntity>() {
            @Override
            public void onSuccess(SettleDiscountAreaEntity discountAreaEntity) {
                isDiscountReturn = true;
                mView.setDiscountAreaInfo(discountAreaEntity);
                checkRefreshDone();
            }

            @Override
            public void onError(BaseResponse response) {
                isDiscountReturn = true;
                mView.showError(response.getMsg());
                checkRefreshDone();
            }
        };

        HashMap<String, String> settleMap = new HashMap<>();
        settleMap.put("goods", goodsJson);
        settleMap.put("isTimeCard", ACT_SettleAccounts.SETTLE_ORDER_TYPE_TIMES_CARD.equals(orderType) ? "1" : "0");
        settleMap.put("memberId", StringUtils.get(memberId));
        settleMap.put("levelId", StringUtils.get(levelId));
        settleMap.put("memberRank", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getMemberPriceLevelId()));
        settleMap.put("memberDiscountType", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getDiscountType()));
        settleMap.put("memberDiscountRatio", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getMemberDiscount()));
        settleMap.put("orderType", "3".equals(orderType) ? "0" : orderType);

        mRepo.getDiscountAreaInfo(settleMap, callback);
        addSubscrebe(callback);
        isDiscountReturn = false;

    }

    /**
     * 计算结账页面右上角订单金额信息
     */
    private void calculateGoodsAmount() {
        ApiCallBack<SettleCalculatePriceEntity> callback = new ApiCallBack<SettleCalculatePriceEntity>() {
            @Override
            public void onSuccess(SettleCalculatePriceEntity settleMemberEntity) {
                isCalculateReturn = true;
                mView.setSettleInfo(settleMemberEntity);
                preIndex = selectedIndex;
                orderVo = settleMemberEntity.getOrderVo();
                // 取出最新的订单金额、待收金额以及可能有的抹零金额
                totalAmount = settleMemberEntity.getTotalAmount();
                toPayAmount = StringUtils.getFormattedMoney(settleMemberEntity.getToPayAmount());
                List<SettleCalculatePriceEntity.DiscountItemBean> discountList = settleMemberEntity.getDiscountItem();
                if (!ListUtil.isListEmpty(discountList)) {
                    for (SettleCalculatePriceEntity.DiscountItemBean item : discountList) {
                        int discountType = item.getDiscountType();
                        if (discountType == TYPE_ERASE_ZERO) {
                            eraseAmount = Double.parseDouble(item.getDiscount());
                        }
                    }
                }

                if (!ListUtil.isListEmpty(timesCards)) {
                    timeCardNumMap.clear();
                    for (TimeCardEntity bean : timesCards) {
                        timeCardNumMap.put(bean.getId(), String.valueOf(bean.getCardNum()));
                    }
                }

                checkRefreshDone();
            }

            @Override
            public void onError(BaseResponse response) {
                isCalculateReturn = true;
                mView.showError(response.getMsg());
                if (response.getCode() == CODE_BUSINESS_ERROR || response.getCode() == 400 || response.getCode() == -1) {
                    revertToLastRequest();
                }
                checkRefreshDone();
            }
        };

        HashMap<String, String> settleMap = new HashMap<>();
        settleMap.put("goods", goodsJson);
        settleMap.put("memberCompanyId", StringUtils.get(memberId));
        settleMap.put("tickets", JSON.toJSONString(formatTicketArray()));
        settleMap.put("mlAmount", StringUtils.get(mlAmount));
        settleMap.put("memberRank", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getMemberPriceLevelId()));
        settleMap.put("memberDiscountType", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getDiscountType()));
        settleMap.put("memberDiscountRatio", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getMemberDiscount()));
        settleMap.put("integral", StringUtils.get(integral));
        settleMap.put("levelId", StringUtils.get(levelId));
        settleMap.put("settleType", settleType);
        if ("2".equals(settleType)) {//次卡
            settleMap.put("goodsType", "2");
        }

        mRepo.calculateGoodsPrice(settleMap, callback);
        isCalculateReturn = false;
        addSubscrebe(callback);

    }

    private void revertToLastRequest() {
        ArrayList<TicketEntity> lastTicket = new ArrayList<>();
        for (TicketEntity ticket : tickets) {
            if (ticket.getIndex() <= preIndex) {
                lastTicket.add(ticket);
            }
        }
        this.tickets = lastTicket;
        mView.showCouponSelectedChange(SettleCalculatePriceEntity.DiscountItemBean.TYPE_COUPON, ListUtil.deepCopy(tickets));


        ArrayList<TimeCardEntity> lastTimesCard = new ArrayList<>();
        for (TimeCardEntity timesCard : timesCards) {
            String cardNum = timeCardNumMap.get(timesCard.getId());
            if (timesCard.getIndex() <= preIndex) {
                if (!StringUtils.isEmpty(cardNum)) {
                    timesCard.setCardNum(Integer.valueOf(cardNum));
                }
                lastTimesCard.add(timesCard);
            }
        }
        this.timesCards = lastTimesCard;

        ArrayList<TicketEntity> lastActivity = new ArrayList<>();
        for (TicketEntity ticket : activityList) {
            if (ticket.getIndex() <= preIndex) {
                lastActivity.add(ticket);
            }
        }
        this.activityList = lastActivity;
        mView.showCouponSelectedChange(SettleCalculatePriceEntity.DiscountItemBean.TYPE_ACTIVITY, ListUtil.deepCopy(activityList));


        HashMap<String, TicketEntity> lastAddedPayMap = new HashMap<>();
        for (String key : addedPayMap.keySet()) {
            TicketEntity payItem = addedPayMap.get(key);
            if (payItem.getIndex() <= preIndex) {
                lastAddedPayMap.put(key, payItem);
            }
        }
        this.addedPayMap = lastAddedPayMap;

        mView.showTimeCardSelectedChange(ListUtil.deepCopy(timesCards));
        selectedIndex = preIndex;
    }

    private List<TicketEntity> formatTicketArray() {
        List<TicketEntity> ticketList = new ArrayList<>();
        ticketList.addAll(tickets);
        ticketList.addAll(activityList);
        for (TimeCardEntity bean : timesCards) {
            TicketEntity coupon = new TicketEntity();
            coupon.setTicketId(bean.getId());
            coupon.setTicketName(bean.getGoodsName());
            coupon.setTicketType(TYPE_TIMES_CARD);
            coupon.setCardNum(bean.getCardNum());
            coupon.setIndex(bean.getIndex());
            ticketList.add(coupon);
        }
        for (String key : addedPayMap.keySet()) {
            TicketEntity payItem = addedPayMap.get(key);
            ticketList.add(payItem);
        }
        return ticketList;
    }

    /**
     * 请求生成订单，发起结账；成功后重置扫码状态
     *
     * @param authCode       微信、支付宝付款码
     * @param cashChange     现金找零
     * @param cashCollection 现金收款
     * @param payType        支付方式
     */
    private void requestSaveOrder(final String authCode, String cashChange, String cashCollection, String integralNum, final String payType, final boolean isFacePay) {
        this.isFacePay = isFacePay;
        ApiCallBack<SettleResultEntity> saveOrderCallback = new ApiCallBack<SettleResultEntity>() {
            @Override
            public void onSuccess(SettleResultEntity settleResultEntity) {
                mView.dismissLoadingDialog();

                // 回调成功后标记允许扫码，并将结果返回给 View 层
                if (!StringUtils.isEmpty(settleResultEntity.getPayCode()) && "1000".equals(settleResultEntity.getPayCode())
                        && !StringUtils.isEmpty(settleResultEntity.getOrderCode())) {
                    if (!AppUtil.isAppSunMiVersion()) {
                        mView.showSettleError(400, "当前安装App非商米版本,请下载商米版本后重试~");
                        return;
                    }
                    if (!AppUtil.isSunMiPos()) {
                        mView.showSettleError(400, "非商米POS,无法使用商米支付~");
                        return;
                    }
                    orderId = settleResultEntity.getOrderCode();
                    payCountDownTimer.bindData(settleResultEntity.getOrderCode());
                    JSONObject jsonObject = JSON.parseObject(payType);
                    String payValue = "0";
                    for (String key : jsonObject.keySet()) {
                        payValue = (String) jsonObject.get(key);
                    }
                    double amount = BigDecimalUtil.mul(payValue, "100");//商米支付金额单位为分
                    requestSunMiPay(settleResultEntity.getOrderCode(), settleResultEntity.getOrderCode(), authCode, (long) amount, isFacePay);
                } else {
                    orderId = "";
                    if (isExecutedScan || isFacePay) {
                        payCountDownTimer.cancel();
                        mView.showTimeChanged(COUNT_DOWN_TIME);
                    }
                    isExecutedScan = false;
                    mView.onSettleSuccess();

                    // 获取订单信息，调用打印
                    requestOrderInfo(settleResultEntity.getSaleId());
                }
            }

            @Override
            public void onError(BaseResponse response) {
                orderId = "";
                if (isExecutedScan || isFacePay) {
                    payCountDownTimer.cancel();
                    mView.showTimeChanged(COUNT_DOWN_TIME);
                }
                mView.dismissLoadingDialog();
                isExecutedScan = false;
                if (CODE_BANK_TIME_OUT == response.getCode()) {
                    saleId = response.getMsg();
                    Elog.e("LJT", " 504 ---> " + response.getMsg());
                }
                mView.showSettleError(response.getCode(), response.getMsg());
            }
        };

        HashMap<String, String> settleMap = new HashMap<>();
        settleMap.put("goods", goodsJson);
        settleMap.put("memberCompanyId", StringUtils.get(memberId));
        settleMap.put("levelId", StringUtils.get(levelId));
        settleMap.put("memberIntegral", StringUtils.get(memberIntegral));
        settleMap.put("phone", StringUtils.get(phone));
        settleMap.put("tickets", JSON.toJSONString(formatTicketArray()));
        settleMap.put("mlAmount", StringUtils.get(mlAmount));
        settleMap.put("memberRank", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getMemberPriceLevelId()));
        settleMap.put("memberDiscountType", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getDiscountType()));
        settleMap.put("memberDiscountRatio", memberEntity == null ? ""
                : StringUtils.get(memberEntity.getMemberDiscount()));
        settleMap.put("integral", StringUtils.get(integral));
        settleMap.put("integralNum", StringUtils.get(integralNum));
        settleMap.put("settleType", StringUtils.get(settleType));
        settleMap.put("posCode", DeviceIdUtils.getDeviceId());
        settleMap.put("totalAmount", MoneyFormatUtil.getFormattedMoney(totalAmount, true));
        settleMap.put("toPayAmount", MoneyFormatUtil.getFormattedMoney(toPayAmount, true));
        settleMap.put("authCode", StringUtils.get(authCode));
        settleMap.put("cashChange", StringUtils.get(cashChange));
        settleMap.put("orderVo", JSON.toJSONString(orderVo));
        settleMap.put("cashCollection", StringUtils.get(cashCollection));
        settleMap.put("salesmanId", StringUtils.get(salesmanId));
        settleMap.put("payType", StringUtils.get(payType));
        settleMap.put("storeType", String.valueOf(storeType));
        settleMap.put("integralDrawNum", StringUtils.get(howMoneyOne));
        settleMap.put("integralList", JSON.toJSONString(integralList));
        mRepo.getSettleResultInfo(settleMap, saveOrderCallback);
        addSubscrebe(saveOrderCallback);

        String cashInput = "";
        if (null != payTypeMap.get(BillUtil.PAY_TYPE_CASH)) {
            cashInput = payTypeMap.get(BillUtil.PAY_TYPE_CASH);
        } else if (!addedPayMap.isEmpty() && null != addedPayMap.get(BillUtil.PAY_TYPE_CASH)) {
            cashInput = addedPayMap.get(BillUtil.PAY_TYPE_CASH).getTicketAmount();
        }

        if (Double.valueOf(BigDecimalUtil.getNumber(cashInput)) != 0) {
            mView.openDrawer();
        }
    }

    private void requestSunMiPay(String businessId, String orderId, String code, long amount, boolean isFacePay) {
        JSONObject jsonObject = new JSONObject();
        isSunMiPay = true;
        jsonObject.put("appType", isFacePay ? "51" : "01");//应用类型 00:银行卡应用 01:聚合扫码支付应用 02:银行卡+银联扫码支付应用 51：扫脸支付
        jsonObject.put("transType", "00");// 交易类型 00－消费  09-退款
        jsonObject.put("appId", BuildConfig.APPLICATION_ID);// 包名
        jsonObject.put("businessId", businessId);// 业务订单号
        jsonObject.put("orderId", orderId);// 支付订单号
        jsonObject.put("amount", amount);// 金额
        jsonObject.put("payCode", code);// 付款码
        JSONObject config = new JSONObject();
        config.put("processDisplay", false);//是否显示支付进行中页面
        config.put("resultDisplay", false);//是否显示交易结果页
        config.put("printTicket", false);//打印小票
        jsonObject.put("config", config);// ui设置

        Elog.e("SUNMI_PAY", "请求参数：" + jsonObject.toJSONString());
        PaymentService.getInstance().callPayment(jsonObject.toJSONString());
    }

    @Override
    public void querySmPayOrderInfo(final boolean isSilent) {
        final ApiCallBack<SettleResultEntity> callBack = new ApiCallBack<SettleResultEntity>() {
            @Override
            public void onSuccess(SettleResultEntity settleResultEntity) {

                if (isExecutedScan || isFacePay) {
                    payCountDownTimer.cancel();
                    mView.showTimeChanged(COUNT_DOWN_TIME);
                }
                isExecutedScan = false;
                isFirstSunMiTimeOut = true;
                mView.onSettleSuccess();

                // 获取订单信息，调用打印
                requestOrderInfo(settleResultEntity.getSaleId());
            }

            @Override
            public void onError(BaseResponse response) {
                if (CODE_SUN_MI_QUERY_TIME_OUT == response.getCode()) {
                    querySmPayOrderInfo(true);
                    return;
                }
                if (response.getCode() != CODE_NET_ERROR) {
                    if (isExecutedScan || isFacePay) {
                        payCountDownTimer.cancel();
                        mView.showTimeChanged(COUNT_DOWN_TIME);
                    }
                    mView.dismissLoadingDialog();
                    isExecutedScan = false;
                    isFirstSunMiTimeOut = true;
                    if (CODE_BANK_TIME_OUT == response.getCode()) {
                        saleId = response.getMsg();
                        Elog.e("LJT", " 504 ---> " + response.getMsg());
                    }
                    mView.showSettleError(response.getCode(), response.getMsg());
                }
            }

            @Override
            public void onNetworkError(BaseResponse response) {
                isSunMiNetError = true;
                if (!isSilent) {
                    mView.showSunMiPayNetError();
                }
            }
        };
        mRepo.querySmPayOrderInfo(orderId, callBack);
        addSubscrebe(callBack);
    }


    /**
     * 根据传入的手机号请求会员详情
     * <p>
     * 1. phone 不为空，查会员详情 -> 订单信息带入或者手动输入手机号
     * 2. phone 为空，不查会员详情 -> 第一次进入结账时
     */
    private boolean requestMemberInfo() {
        if (!TextUtils.isEmpty(phone)) {
            ApiCallBack<MemberEntity> getMemberInfoCallback = new ApiCallBack<MemberEntity>() {
                @Override
                public void onSuccess(MemberEntity settleMemberEntity) {


                    if (settleMemberEntity.getMemberId() == null) {
                        mView.showError("会员信息返回结果为空，请检查!");
                        return;
                    }

                    memberId = settleMemberEntity.getMemberId();
                    memberIntegral = settleMemberEntity.getMemberPoints();
                    howMoneyOne = settleMemberEntity.getHowMoneyOne();
                    levelId = settleMemberEntity.getLevelId();
                    phone = settleMemberEntity.getPhone();
                    memberEntity = settleMemberEntity;

                    // 回调到 View 层，设置页面显示
                    mView.setMemberInfo(settleMemberEntity);

                    requestMemberAccount();

                    // 计算金额以及查询优惠活动
//                    if (orderType.equals(ACT_SettleAccounts.SETTLE_ORDER_TYPE_GOODS)) {
//                        syncRemoteGoodsPrice();
//                    } else {
                    calculateGoodsAmount();
                    requestDiscountAreaInfo();
//                    }
                }

                @Override
                public void onError(BaseResponse response) {
                    mView.showError(response.getMsg());
                }
            };
            mRepo.getMemberInfo(phone, getMemberInfoCallback);
            addSubscrebe(getMemberInfoCallback);
            return true;
        } else {
            memberId = "";
            phone = "";
            levelId = "";
            memberIntegral = "";
            howMoneyOne = "";
            integralList = new ArrayList<>();
            mView.setMemberInfo(null);
        }
        return false;
    }


    private void syncRemoteGoodsPrice() {
        ApiCallBack<PageListResponse<GoodsEntity>> callBack = new ApiCallBack<PageListResponse<GoodsEntity>>() {
            @Override
            public void onSuccess(PageListResponse<GoodsEntity> response) {
                if (!ListUtil.isListEmpty(response.getList())) {
                    List<GoodsEntity> localGoodsList = JSON.parseArray(goodsJson, GoodsEntity.class);
                    for (GoodsEntity localGood : localGoodsList) {
                        for (GoodsEntity remoteGood : response.getList()) {
                            if (localGood.getGoodsSkuId().equals(remoteGood.getGoodsSkuId())) {
                                localGood.setPrice(remoteGood.getPrice());
                                localGood.setMemberPrice(remoteGood.getMemberPrice());
                                localGood.setSecondPrice(remoteGood.getSecondPrice());
                                break;
                            }
                        }
                    }
                    goodsJson = JSON.toJSONString(localGoodsList);
                }
                calculateGoodsAmount();
                requestDiscountAreaInfo();
            }

            @Override
            public void onError(BaseResponse response) {
                calculateGoodsAmount();
                requestDiscountAreaInfo();
            }
        };
        List<String> goodsIds = new ArrayList<>();
        List<GoodsEntity> goodsList = JSON.parseArray(goodsJson, GoodsEntity.class);
        for (GoodsEntity goodsEntity : goodsList) {
            goodsIds.add(goodsEntity.getGoodsSkuId());
        }
        goodsRepository.selectGoodsPrice(JSON.toJSONString(goodsIds), memberEntity, callBack);
        addSubscrebe(callBack);
    }

    /**
     * 生成订单并支付成功后，获取订单信息，执行打印
     *
     * @param saleId 订单id
     */
    public void requestOrderInfo(String saleId) {

        ApiCallBack<BillDetailEntity> billDetailCallBack = new ApiCallBack<BillDetailEntity>() {
            @Override
            public void onSuccess(BillDetailEntity billDetailEntity) {
                mView.dismissLoadingDialog();
                mView.doPrintAfterSettleSuccess(billDetailEntity);
            }

            @Override
            public void onError(BaseResponse response) {
                mView.dismissLoadingDialog();
                mView.showGetBillError();
                mView.showError(response.getMsg());
            }
        };
        mView.showLoadingDialog();
        String billType = "";
        if ("3".equals(orderType)) {
            billType = "0";
        } else if ("2".equals(orderType)) {
            billType = "1";
        } else {
            billType = orderType;
        }
        mBillRepo.getBillDetail(saleId, billType, billDetailCallBack);
        addSubscrebe(billDetailCallBack);

    }


    @Override
    public void searchMember(String text) {
        if (!PatternUtils.isMobileNO(text)) {
            mView.showError("手机号格式不正确");
            return;
        }

        ApiCallBack<MemberEntity> callBack = new ApiCallBack<MemberEntity>() {
            @Override
            public void onSuccess(MemberEntity memberEntity) {
                if (!StringUtils.isEmpty(appointmentId)) {
                    doUpdateReserveMember(appointmentId, memberEntity);
                } else {
                    RxBus.getDefault().post(new MemberBindEvent(memberEntity));
                }
                setPhone(memberEntity.getPhone());
                getMemberOrBillInfo();
                mView.showSearchMemberSuccess();
                mView.showLoadingDialog();
            }

            @Override
            public void onError(BaseResponse response) {
                mView.showError(response.getMsg());
            }
        };
        memberRepository.getMemberInfoByPhone(text, callBack);
        addSubscrebe(callBack);
    }

    private void requestMemberAccount() {
        if (StringUtils.isEmpty(memberId)) {
            return;
        }
        ApiCallBack<MemberAccountEntity> callBack = new ApiCallBack<MemberAccountEntity>() {
            @Override
            public void onSuccess(MemberAccountEntity result) {
                memberAccount = result;
                mView.showMemberAccountInfo(result.getCompanyPrice(), result.getShopPrice());
            }

            @Override
            public void onError(BaseResponse response) {
                mView.showError(response.getMsg());
            }
        };
        memberRepository.getMemberStoreList(memberId, callBack);
        addSubscrebe(callBack);
    }

    @Override
    public void doQuicklyAddMember(final String phone, String name, String gender, String level) {
        if (!isInputLegal(name, phone, level)) {
            return;
        }
        ApiCallBack<MemberEntity> callBack = new ApiCallBack<MemberEntity>() {
            @Override
            public void onSuccess(MemberEntity memberEntity) {
                if (!StringUtils.isEmpty(appointmentId)) {
                    doUpdateReserveMember(appointmentId, memberEntity);
                } else {
                    memberEntity.setMemberId(memberEntity.getId());
                    RxBus.getDefault().post(new MemberBindEvent(memberEntity));
                }
                setPhone(memberEntity.getPhone());
                getMemberOrBillInfo();
                mView.showAddMemberSuccess();
            }

            @Override
            public void onError(BaseResponse response) {
                mView.showError(response.getMsg());
            }
        };
        memberRepository.createNewMember(name, phone, gender, level, "",
                "", "", "", "", callBack);
    }

    @Override
    public void loadShopUserList() {
        ApiCallBack<PageListResponse<ShopUserEntity>> callBack = new ApiCallBack<PageListResponse<ShopUserEntity>>() {
            @Override
            public void onSuccess(PageListResponse<ShopUserEntity> response) {
                mView.dismissLoadingDialog();
                ArrayList<ServerEntity> servers = new ArrayList<>();
                if (!ListUtil.isListEmpty(response.getList())) {
                    for (ShopUserEntity entity : response.getList()) {
                        ServerEntity serverEntity = new ServerEntity();
                        serverEntity.setTechnicianId(entity.getId());
                        serverEntity.setTechnicianName(entity.getName());
                        serverEntity.setTechnicianLabel(entity.getTypeName());
                        servers.add(serverEntity);
                    }
                }
                mView.showServerList(servers);
            }

            @Override
            public void onError(BaseResponse response) {
                mView.dismissLoadingDialog();
                mView.showError(response.getMsg());

            }
        };
        userRepository.getShopUserList(callBack);
        addSubscrebe(callBack);
    }

    @Override
    public void executeFacePay() {
        requestSaveOrder("", "", "", "", JSON.toJSONString(payTypeMap), true);
        mView.showWaitingDialog(true);
        payCountDownTimer.reset();
        payCountDownTimer.start();
    }


    private boolean isInputLegal(String name, String phone, String level) {

        if (TextUtils.isEmpty(name)) {
            mView.showError("请输入会员姓名");
            return false;
        }

        if (!PatternUtils.checkName(name)) {
            mView.showError("会员姓名不能输入特殊字符");
            return false;
        }

        if (!PatternUtils.isMobileNO(phone)) {
            mView.showError("手机号格式不正确");
            return false;
        }

        if (TextUtils.isEmpty(level)) {
            mView.showError("请选择会员等级");
            return false;
        }

        return true;
    }

    public void doUpdateReserveMember(String appointmentId, final MemberEntity memberEntity) {
        ApiCallBack<String> callBack = new ApiCallBack<String>() {
            @Override
            public void onSuccess(String s) {
                memberEntity.setMemberId(memberEntity.getId());
                RxBus.getDefault().post(new MemberBindEvent(memberEntity));
            }

            @Override
            public void onError(BaseResponse response) {
                mView.showError(response.getMsg());
            }
        };
        reserveRepository.updateAppointmentInfo(appointmentId, null != memberEntity ? memberEntity.getId() : "", callBack);
        addSubscrebe(callBack);
    }


    /**
     * 获取最大抹零金额
     */
    public void getMaxValueForEraseDialog() {
        ApiCallBack<String> apiCallBack = new ApiCallBack<String>() {
            @Override
            public void onSuccess(String ceilingAmount) {
                mView.dismissLoadingDialog();
                double maxPayAmount = BigDecimalUtil.add(toPayAmount, String.valueOf(eraseAmount));
                double displayAmount;
                if (Double.parseDouble(ceilingAmount) == -1.0) {//抹零限额 = -1 表示无限制
                    displayAmount = maxPayAmount;
                } else if (maxPayAmount > Double.parseDouble(ceilingAmount)) {
                    displayAmount = Double.parseDouble(ceilingAmount);
                } else {
                    displayAmount = maxPayAmount;
                }
                mView.showEraseDialog(displayAmount);
            }

            @Override
            public void onError(BaseResponse response) {
                mView.dismissLoadingDialog();
                mView.showError(response.getMsg());
            }
        };

        mView.showLoadingDialog();
        mRepo.getEraseCeilingAmount(apiCallBack);
        addSubscrebe(apiCallBack);

    }

    /**
     * 银行卡支付超时后，清空购物车
     * 利用 errorMsg 中的 saleId 查询订单详情，调用打印
     */
    public void requestOrderInfoAfterTimeOut() {
        if (TextUtils.isEmpty(saleId)) {
            mView.showError("订单 id 为空！");
            return;
        }

        ApiCallBack<String> apiCallBack = new ApiCallBack<String>() {
            @Override
            public void onSuccess(String ceilingAmount) {
                mView.onSettleSuccess();
                requestOrderInfo(saleId);
            }

            @Override
            public void onError(BaseResponse response) {
                mView.showError(response.getMsg());
            }
        };

        mRepo.clearGoodsCart(AppConstants.TEMP_SHOP_ID, apiCallBack);
        addSubscrebe(apiCallBack);

    }

    public MemberAccountEntity getMemberAccount() {
        return memberAccount;
    }

    public String getToPayAmount() {
        return toPayAmount;
    }

    public String calculateCouponPrice(List<TicketEntity> selectedItemList) {
        double price = 0;
        if (!ListUtil.isListEmpty(selectedItemList)) {
            for (TicketEntity entity : selectedItemList) {
                double discountAmount = 0;
                if (entity.getTicketType() == TicketEntity.TICKET_TYPE_EXPERIMENT) {
                    discountAmount = BigDecimalUtil.sub(entity.getServiceList().get(0).getPrice(), entity.getTicketAmount());
                } else {
                    discountAmount = Double.parseDouble(entity.getTicketAmount());
                }
                price = BigDecimalUtil.add(String.valueOf(price), String.valueOf(discountAmount));
            }
        }
        return String.valueOf(price);
    }

    public String calculateSelectCardCount(List<TimeCardEntity> selectedItemList) {
        int count = 0;
        if (!ListUtil.isListEmpty(selectedItemList)) {
            for (TimeCardEntity entity : selectedItemList) {
                count += entity.getCardNum();
            }
        }
        return String.valueOf(count);
    }

    public String calculateSelectCardPrice(List<TimeCardEntity> selectedItemList) {
        double price = 0;
        if (!ListUtil.isListEmpty(selectedItemList)) {
            for (TimeCardEntity entity : selectedItemList) {
                price = BigDecimalUtil.add(String.valueOf(price),
                        String.valueOf(BigDecimalUtil.mul(String.valueOf(entity.getServicePrice()), String.valueOf(entity.getCardNum()))));
            }
        }
        return String.valueOf(price);
    }


    public boolean isSelectSameAccount(boolean isShopAccount) {
        if (addedPayMap.isEmpty()) {
            return true;
        }

        boolean isAccountSelected = false;
        for (String key : addedPayMap.keySet()) {
            if (BillUtil.PAY_TYPE_BALANCE.equals(key)) {
                isAccountSelected = true;
                break;
            }
        }
        if (!isAccountSelected) {
            return true;
        }

        if (isShopAccount) {
            return storeType == LoginEntity.STORE_TYPE_SHOP;
        } else {
            return storeType == LoginEntity.STORE_TYPE_COMPANY;
        }
    }

    @Override
    public void detachView() {
        super.detachView();

        if (payCountDownTimer != null) {
            payCountDownTimer.cancel();
        }
    }

    public void setIntegralList(List<GoodsEntity> integralList) {
        this.integralList = integralList;
    }

    public List<GoodsEntity> getIntegralList() {
        return integralList;
    }

    public boolean isSunMiPay() {
        return isSunMiPay;
    }

    public void setSunMiPay(boolean sunMiPay) {
        isSunMiPay = sunMiPay;
    }


    public boolean isBindMember() {
        if (TextUtils.isEmpty(memberId)) {
            mView.showError("请登录会员后重试");
            return false;
        }

        if (TextUtils.isEmpty(memberIntegral) || Double.parseDouble(BigDecimalUtil.getNumber(memberIntegral)) == 0) {
            mView.showError("会员积分不足，无法进行换购");
            return false;
        }
        return true;
    }

    public boolean isBindMemberForPopup() {
        return !TextUtils.isEmpty(memberId);
    }

    private void checkRefreshDone() {
        if (isDiscountReturn && isCalculateReturn) {
            mView.showRefreshDone();
            mView.dismissLoadingDialog();
        }
    }


}
